package com.borya.service.web.impl;

import io.netty.handler.codec.http.multipart.FileUpload;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSONObject;
import com.borya.dao.UploadSourceDAO;
import com.borya.framework.annotation.Autowired;
import com.borya.framework.annotation.Component;
import com.borya.framework.util.ObjectUtils;
import com.borya.model.entity.CardSource;
import com.borya.model.entity.FileInfo;
import com.borya.model.entity.PhoneSource;
import com.borya.model.entity.SelectInfo;
import com.borya.service.web.UploadSourceService;
import com.borya.statuscode.StatusCode;
import com.borya.util.AliOSSUtil;
import com.borya.util.AliOSSUtil.UploadResult;
import com.borya.util.Constant;
import com.borya.util.DateUtils;
import com.borya.util.ReadExcel;

@Component("uploadSourceServiceImpl")
public class UploadSourceServiceImpl implements UploadSourceService{

    private Logger log = Logger.getLogger(getClass());

    @Autowired("uploadSourceDAOImpl")
    private UploadSourceDAO sourceDAO;


    public UploadSourceDAO getSourceDAO() {
        return sourceDAO;
    }

    public void setSourceDAO(UploadSourceDAO sourceDAO) {
        this.sourceDAO = sourceDAO;
    }

    @Override
    public String phoneSource(FileUpload fileUpload) {
        try {
            String fileName = fileUpload.getFilename();
            if(!fileName.endsWith(".txt")){
                log.warn("文件类型错误");
                return StatusCode.PARAM_ERROR.toJSON("文件类型错误");
            }
            FileInfo fileInfo = FileInfo.newInstance(Constant.SpecialTag.SOURCE, "phone", fileName);
            if (fileUpload.isCompleted()) {
                File dir = new File(fileInfo.getParentPath());
                if (!dir.exists()) {
                    dir.mkdirs();
                }
                File dest = new File(dir, fileName);
                boolean r = fileUpload.renameTo(dest);
                if(! r){
                    log.warn("创建文件失败");
                    return StatusCode.SYSTEM_EXCEPTION.toJSON();
                }
                return readTxtPhone(fileInfo.getFilePath());
            }

        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return StatusCode.SYSTEM_EXCEPTION.toJSON();
    }

    /**
     * 号码资源入库
     * @param filePath 文件路径
     * @throws IOException
     */
    private String readTxtPhone(String filePath) throws IOException{
        Map<String, String> smspMap = getSourceDAO().saveSmsp();
        if(smspMap == null){
            log.warn("获取smsp列saveSmsp return null,"+filePath);
            return StatusCode.SYSTEM_EXCEPTION.toJSON("smsp队列获取错误");
        }

        List<String> stringList = getStringList(filePath);
        if(stringList == null || stringList.isEmpty()){
            log.warn("无内容");
            return StatusCode.SYSTEM_EXCEPTION.toJSON("文件为空或未获取到文件内容");
        }
        Map<String, SelectInfo> selMap = getSourceDAO().getLevelCode();
        if(selMap == null){
            log.error("getLevelCode return null");
            return StatusCode.SYSTEM_EXCEPTION.toJSON();
        }
        String[] titles = stringList.get(0).split(",",-1);
        List<PhoneSource> list = dealList(filePath, stringList, titles
                , smspMap, 1, new HashMap<>(),selMap);
        if(list == null || list.isEmpty()){
            log.warn("数据处理结果为空");
            return StatusCode.SYSTEM_EXCEPTION.toJSON("处理失败");
        }

        boolean res = getSourceDAO().insertPhoneSource(list);
        if(! res){
            log.warn("insert phone source false,"+filePath);
            return StatusCode.SYSTEM_EXCEPTION.toJSON("入库失败");
        }
        log.debug("入库成功,"+filePath);
        getSourceDAO().updLog();
        return StatusCode.SUCCESS.toJSON();
    }
    

    @Override
    public String unicomPhoneSource(FileUpload fileUpload) {
        try {
            String fileName = fileUpload.getFilename();
            if(!fileName.endsWith(".xls")){
                log.warn("文件类型错误");
                return StatusCode.PARAM_ERROR.toJSON("文件类型错误");
            }
            FileInfo fileInfo = FileInfo.newInstance(Constant.SpecialTag.SOURCE, "unicomphone", fileName);
            if (fileUpload.isCompleted()) {
                File dir = new File(fileInfo.getParentPath());
                if (!dir.exists()) {
                    dir.mkdirs();
                }
                File dest = new File(dir, fileName);
                boolean r = fileUpload.renameTo(dest);
                if(! r){
                    log.warn("创建文件失败");
                    return StatusCode.SYSTEM_EXCEPTION.toJSON();
                }
                return readTxtUnicomPhone(fileInfo.getFilePath());
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return StatusCode.SYSTEM_EXCEPTION.toJSON();
    }

    /**
     * 号码资源入库
     * @param filePath 文件路径
     * @throws IOException
     */
    private String readTxtUnicomPhone(String filePath) throws IOException{
        List<String> stringList = getStringList(filePath);
        if(stringList == null || stringList.isEmpty()){
            log.warn("无内容");
            return StatusCode.SYSTEM_EXCEPTION.toJSON("文件为空或未获取到文件内容");
        }
        Map<String, String> smspMap = getSourceDAO().saveSmsp();
        if(smspMap == null){
            log.warn("获取smsp列saveSmsp return null,"+filePath);
            return StatusCode.SYSTEM_EXCEPTION.toJSON("smsp队列获取错误");
        }
        Map<String, String> phoneModelMap = getSourceDAO().saveNumberRule();
        if(phoneModelMap == null){
            log.warn("获取资源模式sql return null");
            return StatusCode.SYSTEM_EXCEPTION.toJSON("号码渠道未找到");
        }
        Map<String, SelectInfo> selMap = getSourceDAO().getLevelCode();
        if(selMap == null){
            log.warn("getLevelCode return null");
            return StatusCode.SYSTEM_EXCEPTION.toJSON();
        }
        String[] titles = stringList.get(0).split(",",-1);
        List<PhoneSource> list = dealList(filePath, stringList, titles
                , smspMap, 2,phoneModelMap,selMap);
        if(list == null || list.isEmpty()){
            log.info("数据处理结果为空");
            return StatusCode.SYSTEM_EXCEPTION.toJSON("处理失败");
        }
        boolean res = getSourceDAO().insertUnicomPhoneSource(list);
        list.clear();
        if(! res){
            log.warn("insert phone source false,"+filePath);
            return StatusCode.SYSTEM_EXCEPTION.toJSON("入库失败");
        }
        log.debug("入库成功,"+filePath);
        getSourceDAO().updLog();
        return StatusCode.SUCCESS.toJSON();
    }

    /**
     *
     * @param str
     * @param line
     * @param smspMap
     * @param titles
     * @param type 1远特2联通
     * @return
     */
    private PhoneSource doChange(String str,int line
            ,Map<String, String> smspMap, String[] titles,int type
            ,Map<String, String> modelMap){
        PhoneSource source = new PhoneSource();
        String[] arrs = str.split(",",-1);
        switch (type) {
        case 1:
            source.setSourceStr(str);
            source.setSourceLine(line);

            setInfo(source, titles, arrs);
            source.checkSourceYt();

            if(! "0".equals(source.getBigNumberLevel())){
                source.setPretty(1);
                source.setRecommendation(1);
            }
            else{
                source.setPretty(2);
                source.setRecommendation(0);
            }
            source.setCardMoneyCode("0");
            if(!ObjectUtils.isEqual("0",source.getCardMoney())){
                //大众号 无选号费的为0 有的为1
                source.setCardMoneyCode("1");
            }

            source.setSmsp(smspMap.get(source.getCityCode()));
            if(StringUtils.isBlank(source.getSmsp())){
                log.warn("资源smsp错误,"+source.toString());
                source.setSourceTrue(false);
            }
            if(! source.isSourceTrue()){
                log.warn("入表数据有误：line:"+line+",str:"+str);
            }
            source.setPhoneModelType("yuantel");
            break;
        case 2:
            source.setSourceStr(str);
            source.setSourceLine(line);

            setInfo(source, titles, arrs);
            source.checkSourceUnicom();

            source.setPhoneType(2);
            source.setRecommendation(1);
            if(! "0".equals(source.getBigNumberLevel())){
                source.setPretty(1);
                source.setRecommendation(1);
            }
            else{
                source.setPretty(2);
                source.setRecommendation(0);
            }
            source.setSmsp(smspMap.get(source.getCityCode()));
            if(StringUtils.isBlank(source.getSmsp())){
                log.warn("资源smsp错误,"+source.toString());
                source.setSourceTrue(false);
            }
            if(StringUtils.isNotBlank(source.getUnicomDealerId())
                    && modelMap.containsKey(source.getUnicomDealerId()))
                source.setPhoneModelType(modelMap.get(source.getUnicomDealerId()));
            else
                source.setPhoneModelType(modelMap.get("basemodel"));
            break;
        default:
            break;
        }
        source.setRightEight(source.getPhone().substring(3));
        return source;
    }


    @Override
    public String cardSource(FileUpload fileUpload) {
        try {
            String fileName = fileUpload.getFilename();
            FileInfo fileInfo = FileInfo.newInstance(Constant.SpecialTag.SOURCE, "card", fileName);
            if (fileUpload.isCompleted()) {
                File dir = new File(fileInfo.getParentPath());
                if (!dir.exists()) {
                    dir.mkdirs();
                }
                File dest = new File(dir, fileName);
                boolean r = fileUpload.renameTo(dest);
                if(! r){
                    log.info("创建文件失败");
                    return StatusCode.SYSTEM_EXCEPTION.toJSON();
                }
                return readTxtCard(fileInfo.getFilePath());
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return StatusCode.SYSTEM_EXCEPTION.toJSON();
    }

    /**
     * 号码资源入库
     * @param filePath 文件路径
     * @throws IOException
     */
    private String readTxtCard(String filePath) throws IOException{
        List<String> stringList = getStringList(filePath);
        if(stringList == null || stringList.isEmpty()){
            log.warn("无内容");
            return StatusCode.SYSTEM_EXCEPTION.toJSON("文件为空或未获取到文件内容");
        }

        String[] titles = stringList.get(0).split(",",-1);
        List<CardSource> list = dealCardList(filePath, stringList, titles);
        if(list == null || list.isEmpty()){
            log.warn("数据处理结果为空");
            return StatusCode.SYSTEM_EXCEPTION.toJSON("处理失败");
        }
        boolean res = getSourceDAO().insertCardSource(list);
        list.clear();
        if(! res){
            log.warn("insert card source false,"+filePath);
            return StatusCode.SYSTEM_EXCEPTION.toJSON("入库失败");
        }
        log.debug("入库成功,"+filePath);
        return StatusCode.SUCCESS.toJSON();
    }

    private List<CardSource> dealCardList(String filePath,List<String> stringList,String[] titles
    ) throws IOException{
        List<CardSource> list = new ArrayList<>();
        final int fileIndex = filePath.indexOf(".");
        FileWriter fw = new FileWriter(filePath.substring(0,fileIndex)+"error"+filePath.substring(fileIndex));
        BufferedWriter bw = new BufferedWriter(fw);
        for(int i = 1,size = stringList.size();i < size; i++){
            String str = stringList.get(i);
            CardSource each = doChangeCard(str,i,titles);
            if(! each.isSourceTrue()){
                bw.write(each.getSourceStr());
                bw.newLine();
            }
            else{
                list.add(each);
            }
        }
        bw.close();
        return list;
    }

    private CardSource doChangeCard(String str,int line,String[] titles){
        CardSource source = new CardSource();
        source.setSourceStr(str);
        source.setSourceLine(line);
        String[] arrs = str.split(",",-1);
        setCardInfo(source, titles, arrs);
        source.checkCardInfo();
        final int cardType = 20 == source.getIccid().length()?1:2;
        if(1 == cardType
                && source.getCardResourceIdJN().length()==0
                && source.getCardResourceId().length()==0){
            log.warn("卡资源错误:远特卡无card_resource_id,"+source.toString());
            source.setSourceTrue(false);
        }
        source.setCardType(cardType);
        if(source.getIccid().length() >= 19)
            source.setIccid19(source.getIccid().substring(0, 19));
        return source;
    }

    private void setCardInfo(CardSource source,String[] titles,String[] arrs){
        for(int i = 0,size = titles.length;i < size;i++){
            switch (titles[i].toUpperCase()) {
            case "INST_ID":
                break;
            case "ICCID":
                source.setIccid(arrs[i]);
                break;
            case "CITY_CODE":
                source.setCityCode(arrs[i]);
                break;
            case "INST_ID_JINAN":
                source.setCardResourceIdJN(arrs[i]);
                break;
            case "INST_ID_HAERBIN":
                source.setCardResourceId(arrs[i]);
                break;

            default:
                log.info("unknown title:"+titles[i]);
                break;
            }
        }
    }


    private void setInfo(PhoneSource source,String[] titles,String[] arrs){
        for(int i = 0,size = titles.length;i < size;i++){
            switch (titles[i]) {
            case "INST_ID":
                source.setResInstId(arrs[i]);
                break;
            case "PHONE_NUMBER":
                source.setPhone(arrs[i]);
                break;
            case "CITY_CODE":
                source.setCityCode(arrs[i]);
                break;
            case "NUM_RULE_KIND":
                source.setNumberLevel("".equals(arrs[i])?"0":arrs[i]);
                break;
            case "F_LEVEL":
                source.setBigNumberLevel(("".equals(arrs[i])||"99".equals(arrs[i]))?"0":arrs[i]);
                break;
            case "IMSI":
                source.setImsi(arrs[i]);
                break;
            case "BELONGS_TO":
                source.setSourceDealerId(arrs[i]);
                break;
            case "SPECIAL_DISFEE":
                source.setCardMoney(arrs[i]);
                break;
            case "NUMBER_MODEL":
//				source.setPhoneModelType(arrs[i]);
                break;
            case "TF_NUMBER_MODEL":
                source.setTfPhoneModelType(arrs[i]);
                break;
            case "BEFOREHAND_FEE":
                break;
            case "ADJUST_MONTHS":
                break;
            case "ADJUST_FEE":
                break;
            case "WORK_NO":
                break;
            case "UNICOM_DEALER_ID":
                source.setUnicomDealerId(arrs[i]);
                break;
            default:
                log.warn("unknown title:"+titles[i]);
                break;
            }
        }
    }


    /**
     *
     * @param filePath
     * @param stringList
     * @param titles
     * @param smspMap
     * @param type 1远特2联通
     * @return
     * @throws IOException
     */
    private List<PhoneSource> dealList(String filePath,List<String> stringList,String[] titles
            ,Map<String, String> smspMap,int type
            ,Map<String, String> modelMap, Map<String, SelectInfo> selMap) throws IOException{
        List<PhoneSource> list = new ArrayList<>();
        final int fileIndex = filePath.indexOf(".");
        FileWriter fw = new FileWriter(filePath.substring(0,fileIndex)+"error"+filePath.substring(fileIndex));
        BufferedWriter bw = new BufferedWriter(fw);
        for(int i = 1,size = stringList.size();i < size; i++){
            String str = stringList.get(i);
            PhoneSource each = doChange(str,i,smspMap,titles,type,modelMap);
            if(! each.isSourceTrue()){
                bw.write(each.getSourceStr());
                bw.newLine();
            }
            else{
                if(selMap.containsKey(each.getNumberLevel())){
                    SelectInfo selectInfo = selMap.get(each.getNumberLevel());
                    each.setLevelCode(selectInfo.getLevelCode());
                    each.setBigLevelCode(selectInfo.getBigLevelCode());
                }
                list.add(each);

            }
        }
        bw.close();
        return list;
    }

    private List<String> getStringList(String filePath) throws IOException{
        List<String> list = null;
        File file       = new File(filePath);
        switch (filePath.substring(filePath.lastIndexOf(".")+1,filePath.length())) {
        case "txt":
            FileReader f      = new FileReader(file);
            BufferedReader re = new BufferedReader(f);

            list = new ArrayList<>();
            String str   = re.readLine();
            while(str != null){
                list.add(str);
                str = re.readLine();
            }
            re.close();
            return list;

        case "xls":
            list = ReadExcel.readExcel(file);
            return list;
        default:
            log.info("unknown file type:"+filePath);
            return null;
        }

    }
    @Override
    public String merchantFileUpload(String imgPath,String imgNo, FileUpload fileUpload) {
        try {
            final int lastIndexOf = imgPath.lastIndexOf("/");
            String subPath="";//图片路径
            if(lastIndexOf==-1)
                subPath=Constant.DEFAULT_IMG_SAVE_SUBPATH;
            else
                subPath = imgPath.substring(0,lastIndexOf+1);
            if (fileUpload.isCompleted()) {
                String imgName = "";
                String phone="imgEdit_";
                final String YYMMddHHmmssSSS = DateUtils.format(System.currentTimeMillis(), "YYMMddHHmmssSSS");
                switch(Integer.valueOf(imgNo)){
                case 1:
                    imgName = phone + "registone" +"_"+YYMMddHHmmssSSS+ ".png";
                    break;
                case 2:
                    imgName = phone + "registtwo" + "_"+YYMMddHHmmssSSS+ ".png";
                    break;
                case 3:
                    imgName = phone + "registthree" + "_"+YYMMddHHmmssSSS+ ".png";
                    break;
                case 4:
//    				path = "/sign/";
                    imgName = phone+"_"+YYMMddHHmmssSSS+ ".png";
                    break;
                case 5:
                    imgName = phone + "registfive" + "_"+YYMMddHHmmssSSS+ ".png";
                    break;
                default:
                    log.warn("param imgNo error,imgNo:"+imgNo);
                    return StatusCode.PARAM_ERROR.toJSON("参数照片编号错误");
                }
                //直接上传到oss
                String filePathAndFileName=subPath.substring(1)+imgName;
				UploadResult upload = AliOSSUtil.upload(fileUpload.getFile(), filePathAndFileName);
                if(upload.isFlag()){
                    JSONObject data = new JSONObject();
                    data.put("imgPath", "/"+ filePathAndFileName);
                    return StatusCode.SUCCESS.toDiyJson("data", data);
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return StatusCode.SYSTEM_EXCEPTION.toJSON();
    }
}
